package com.newshub.monitor.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.newshub.monitor.config.MonitorProperties;
import com.newshub.monitor.service.LogAnalysisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 日志分析服务实现类
 */
@Slf4j
@Service
public class LogAnalysisServiceImpl implements LogAnalysisService {

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private MonitorProperties monitorProperties;

    @Override
    public Map<String, Object> getBusinessLogs(String module, String username, String operation, 
                                              LocalDateTime startTime, LocalDateTime endTime, 
                                              Integer pageNum, Integer pageSize) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 过滤业务日志
            List<JsonNode> businessLogs = logs.stream()
                .filter(log -> "INFO".equals(log.path("level").asText()))
                .filter(log -> log.has("module") && !log.path("module").isNull())
                .filter(log -> module == null || module.equals(log.path("module").asText()))
                .filter(log -> username == null || username.equals(log.path("username").asText()))
                .filter(log -> operation == null || log.path("description").asText().contains(operation))
                .collect(Collectors.toList());
            
            // 分页处理
            int total = businessLogs.size();
            int start = (pageNum - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            
            List<JsonNode> pageLogs = businessLogs.subList(start, end);
            
            Map<String, Object> result = new HashMap<>();
            result.put("list", pageLogs);
            result.put("total", total);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            
            return result;
            
        } catch (Exception e) {
            log.error("获取业务操作日志失败", e);
            throw new RuntimeException("获取业务操作日志失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getExceptionLogs(String exceptionType, String alertLevel,
                                               LocalDateTime startTime, LocalDateTime endTime,
                                               Integer pageNum, Integer pageSize) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 过滤异常日志
            List<JsonNode> exceptionLogs = logs.stream()
                .filter(log -> "ERROR".equals(log.path("level").asText()))
                .collect(Collectors.toList());
            
            // 分页处理
            int total = exceptionLogs.size();
            int start = (pageNum - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            
            List<JsonNode> pageLogs = exceptionLogs.subList(start, end);
            
            Map<String, Object> result = new HashMap<>();
            result.put("list", pageLogs);
            result.put("total", total);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            
            return result;
            
        } catch (Exception e) {
            log.error("获取异常日志失败", e);
            throw new RuntimeException("获取异常日志失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> searchLogs(String keyword, String logLevel, String module,
                                         LocalDateTime startTime, LocalDateTime endTime,
                                         Integer pageNum, Integer pageSize) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 过滤日志
            List<JsonNode> filteredLogs = logs.stream()
                .filter(log -> logLevel == null || logLevel.equals(log.path("level").asText()))
                .filter(log -> module == null || module.equals(log.path("module").asText()))
                .filter(log -> keyword == null || 
                    log.path("message").asText().contains(keyword) ||
                    log.path("description").asText().contains(keyword))
                .collect(Collectors.toList());
            
            // 分页处理
            int total = filteredLogs.size();
            int start = (pageNum - 1) * pageSize;
            int end = Math.min(start + pageSize, total);
            
            List<JsonNode> pageLogs = filteredLogs.subList(start, end);
            
            Map<String, Object> result = new HashMap<>();
            result.put("list", pageLogs);
            result.put("total", total);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            
            return result;
            
        } catch (Exception e) {
            log.error("搜索日志失败", e);
            throw new RuntimeException("搜索日志失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getRealtimeLogs(Integer limit, Boolean follow) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 获取最新的日志
            List<JsonNode> recentLogs = logs.stream()
                .sorted((a, b) -> b.path("timestamp").asText().compareTo(a.path("timestamp").asText()))
                .limit(limit)
                .collect(Collectors.toList());
            
            Map<String, Object> result = new HashMap<>();
            result.put("logs", recentLogs);
            result.put("total", recentLogs.size());
            result.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            
            return result;
            
        } catch (Exception e) {
            log.error("获取实时日志失败", e);
            throw new RuntimeException("获取实时日志失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getLogStats(LocalDateTime startTime, LocalDateTime endTime) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            Map<String, Object> stats = new HashMap<>();
            
            // 按级别统计
            Map<String, Long> levelStats = logs.stream()
                .collect(Collectors.groupingBy(
                    log -> log.path("level").asText(),
                    Collectors.counting()
                ));
            
            // 按模块统计
            Map<String, Long> moduleStats = logs.stream()
                .filter(log -> log.has("module") && !log.path("module").isNull())
                .collect(Collectors.groupingBy(
                    log -> log.path("module").asText(),
                    Collectors.counting()
                ));
            
            stats.put("levelStats", levelStats);
            stats.put("moduleStats", moduleStats);
            stats.put("totalLogs", logs.size());
            stats.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            
            return stats;
            
        } catch (Exception e) {
            log.error("获取日志统计信息失败", e);
            throw new RuntimeException("获取日志统计信息失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getUserActivityStats(LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        try {
            String logFile = getTodayLogFile();
            List<JsonNode> logs = readLogFile(logFile);
            
            // 按用户统计活动
            Map<String, Long> userActivity = logs.stream()
                .filter(log -> log.has("username") && !log.path("username").isNull())
                .collect(Collectors.groupingBy(
                    log -> log.path("username").asText(),
                    Collectors.counting()
                ));
            
            // 排序并限制数量
            List<Map.Entry<String, Long>> sortedActivity = userActivity.entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .limit(limit)
                .collect(Collectors.toList());
            
            Map<String, Object> result = new HashMap<>();
            result.put("userActivity", sortedActivity);
            result.put("total", sortedActivity.size());
            
            return result;
            
        } catch (Exception e) {
            log.error("获取用户活动统计失败", e);
            throw new RuntimeException("获取用户活动统计失败: " + e.getMessage());
        }
    }

    /**
     * 读取日志文件
     */
    private List<JsonNode> readLogFile(String logFile) throws IOException {
        List<JsonNode> logs = new ArrayList<>();
        
        if (!Files.exists(Paths.get(logFile))) {
            return logs;
        }
        
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(logFile))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.trim().isEmpty()) continue;
                
                try {
                    JsonNode logEntry = objectMapper.readTree(line);
                    logs.add(logEntry);
                } catch (Exception e) {
                    continue;
                }
            }
        }
        
        return logs;
    }

    /**
     * 获取今日日志文件路径
     */
    private String getTodayLogFile() {
        return monitorProperties.getTodayLogFilePath();
    }
}
